using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using Terminal.Advanced_AEUC_settings_controls.Settings_Interfaces;
using Terminal.Advanced_AEUC_settings_controls.Settings_AUX;
using Terminal.Advanced_AEUC_settings_controls.Settings_Editing_Forms;

namespace Terminal.Advanced_AEUC_settings_controls.Setting_Advanced_Control
{
    class AEUCSettingComboBox : ComboBox, IAEUCSetting, IAEUCEnumeration, IAEUCSerialization
    {
        #region AEUC Setting data
        Int64 aeuc_val;
        Int64 aeuc_opt_val;
        Int64 aeuc_default;
        Int64 aeuc_min;
        Int64 aeuc_max;
        uint aeuc_id;
        uint aeuc_size;
        bool aeuc_enabled;
        bool aeuc_refPtr;
        bool aeuc_support_state_sense;
        bool aeuc_state_changed;
        bool aeuc_linked_setting;
        int next_link_reference_number;
        IAEUCSetting aeuc_next_linked_setting;
        int aeuc_linked_setting_type;
        bool aeuc_isaux;
        int aux_primary_reference_number;
        IAEUCSetting aeuc_aux_primary_link;
        int aux_secondary_reference_number;
        IAEUCSetting aeuc_aux_secondary_link;
        Int64 aeuc_shadow_val;
        bool aeuc_use_shadow_val;
        string aeuc_display_name;
        List<GenAEUCEnumerationItem> enumerationItems;
        #endregion

        #region Constructors
        /// <summary>
        /// Constructor of the advanced aeuc control container
        /// </summary>
        public AEUCSettingComboBox()
            : base()
        {
            AEUC_Enabled = aeuc_enabled = false;
            #region Set possible and default values
            AEUC_Val = aeuc_default = 0;
            aeuc_opt_val = 0;
            aeuc_min = 0;
            aeuc_max = 0;
            #endregion
            aeuc_id = 0;
            aeuc_size = 0;
            aeuc_support_state_sense = aeuc_state_changed = false;
            #region linked state settings
            aeuc_linked_setting = false;
            aeuc_next_linked_setting = null;
            #endregion
            #region auxiliary settings
            aeuc_isaux = true;
            aeuc_aux_primary_link = null;
            aeuc_aux_secondary_link = null;
            #endregion
            #region use of shaowed copy
            aeuc_shadow_val = AEUC_Val;
            aeuc_use_shadow_val = true;
            #endregion
            #region enumeration items
            enumerationItems = new List<GenAEUCEnumerationItem>();
            UpDateIndexSelection();
            #endregion

            aeuc_refPtr = false;

            #region Context menu setup
            EventHandler eh = new EventHandler(ContextMenu);
            ContextMenuStrip =  new ContextMenuStrip();
            ContextMenuStrip.Items.Add("Edit", null, eh);
            ContextMenuStrip.Items.Add("Move", null, eh);
            //ContextMenuStrip.Items.Add("Send", null, eh);
            if (aeuc_enabled)
                ContextMenuStrip.Items.Add("Disable", null, eh);
            else
                ContextMenuStrip.Items.Add("Enable", null, eh);
            #endregion

            AEUC_DisplayName = "AEUC control";
        }

        /// <summary>
        /// Constructor of the advanced aeuc control container
        /// </summary>
        /// <param name="iID">Setting ID</param>
        /// <param name="iSize">Setting size</param>
        /// <param name="iVal">Current value</param>
        /// <param name="iDefVal">Default value</param>
        /// <param name="iMinVal">Minimum value</param>
        /// <param name="iMaxVal">Maximum value</param>
        public AEUCSettingComboBox(uint iID, uint iSize, Int64 iVal, Int64 iDefVal, Int64 iMinVal, Int64 iMaxVal)
            : base()
        {
            AEUC_Enabled = aeuc_enabled = false;
            #region Set possible and default values
            AEUC_Val = iVal;
            aeuc_default = iDefVal;
            aeuc_opt_val = 0;
            aeuc_min = iMinVal;
            aeuc_max = iMaxVal;
            #endregion
            aeuc_id = iID;
            aeuc_size = iSize;
            aeuc_support_state_sense = aeuc_state_changed = false;
            #region linked state settings
            aeuc_linked_setting = false;
            aeuc_next_linked_setting = null;
            #endregion
            #region auxiliary settings
            aeuc_isaux = true;
            aeuc_aux_primary_link = null;
            aeuc_aux_secondary_link = null;
            #endregion
            #region use of shaowed copy
            aeuc_shadow_val = AEUC_Val;
            aeuc_use_shadow_val = true;
            #endregion
            #region enumeration items
            enumerationItems = new List<GenAEUCEnumerationItem>();
            UpDateIndexSelection();
            #endregion

            aeuc_refPtr = false;

            #region Context menu setup
            EventHandler eh = new EventHandler(ContextMenu);
            ContextMenuStrip =  new ContextMenuStrip();
            ContextMenuStrip.Items.Add("Edit", null, eh);
            ContextMenuStrip.Items.Add("Move", null, eh);
            //ContextMenuStrip.Items.Add("Send", null, eh);
            if (aeuc_enabled)
                ContextMenuStrip.Items.Add("Disable", null, eh);
            else
                ContextMenuStrip.Items.Add("Enable", null, eh);
            #endregion

            AEUC_DisplayName = "AEUC control";
        }

        /// <summary>
        /// Constructor of the advanced aeuc control container
        /// </summary>
        /// <param name="iID">Setting ID</param>
        /// <param name="iSize">Setting size</param>
        /// <param name="iVal">Current value</param>
        /// <param name="iDefVal">Default value</param>
        /// <param name="iMinVal">Minimum value</param>
        /// <param name="iMaxVal">Maximum value</param>
        /// <param name="iEnabled">Setting enabled</param>
        /// <param name="iStateSense">Track state changes</param>
        /// <param name="iAux">Use only as uaxiliary control</param>
        /// <param name="iDisplayName">String display name</param>
        public AEUCSettingComboBox(uint iID, uint iSize, Int64 iVal, Int64 iDefVal, Int64 iMinVal, Int64 iMaxVal, bool iEnabled, bool iStateSense, bool iAux, string iDisplayName)
            : base()
        {
            AEUC_Enabled = iEnabled;
            #region Set possible and default values
            AEUC_Val = iVal;
            aeuc_default = iDefVal;
            aeuc_opt_val = 0;
            aeuc_min = iMinVal;
            aeuc_max = iMaxVal;
            #endregion
            aeuc_id = iID;
            aeuc_size = iSize;
            aeuc_support_state_sense = aeuc_state_changed = iStateSense;
            #region linked state settings
            aeuc_linked_setting = false;
            aeuc_next_linked_setting = null;
            #endregion
            #region auxiliary settings
            aeuc_isaux = iAux;
            aeuc_aux_primary_link = null;
            aeuc_aux_secondary_link = null;
            #endregion
            #region use of shaowed copy
            aeuc_shadow_val = AEUC_Val;
            aeuc_use_shadow_val = true;
            #endregion
            #region enumeration items
            enumerationItems = new List<GenAEUCEnumerationItem>();
            UpDateIndexSelection();
            #endregion

            aeuc_refPtr = false;

            #region Context menu setup
            EventHandler eh = new EventHandler(ContextMenu);
            ContextMenuStrip =  new ContextMenuStrip();
            ContextMenuStrip.Items.Add("Edit", null, eh);
            ContextMenuStrip.Items.Add("Move", null, eh);
            //ContextMenuStrip.Items.Add("Send", null, eh);
            if (aeuc_enabled)
                ContextMenuStrip.Items.Add("Disable", null, eh);
            else
                ContextMenuStrip.Items.Add("Enable", null, eh);
            #endregion

            AEUC_DisplayName = iDisplayName;
        }
        #endregion

        #region Context menu handlers
        /// <summary>
        /// Context menu function
        /// </summary>
        new void ContextMenu(object sender, EventArgs ea)
        {
            ToolStripItem tmpItem = (ToolStripItem)sender;
            if (tmpItem.Text == "Edit")
            {
                AEUCSettingEditForm asef = new AEUCSettingEditForm(this);
                asef.ShowDialog();
            }
            else if (tmpItem.Text == "Move")
            {
                Parent.Parent.MouseMove += new MouseEventHandler(Parent_MouseMove);
                tmpItem.Text = "Lock";
            }
            else if (tmpItem.Text == "Lock")
            {
                Parent.Parent.MouseMove -= new MouseEventHandler(Parent_MouseMove);
                tmpItem.Text = "Move";
            }
            //else if (tmpItem.Text == "Send")
                //;
            else if (tmpItem.Text == "Disable")
            {
                tmpItem.Text = "Enable";
                AEUC_Enabled = false;
            }
            else if (tmpItem.Text == "Enable")
            {
                tmpItem.Text = "Disable";
                AEUC_Enabled = true;
            }
        }
        #endregion

        #region Overrided events for control functionality
        /// <summary>
        /// When the value of the nud is changed its state change is also set
        /// </summary>
        /// <param name="e">Event arguments</param>
        protected override void OnSelectedItemChanged(EventArgs e)
        {
            SelectionAltered();
            base.OnSelectedItemChanged(e);
        }
        /// <summary>
        /// When the value of the nud is changed its state change is also set
        /// </summary>
        /// <param name="e">Event arguments</param>
        protected override void OnSelectedIndexChanged(EventArgs e)
        {
            SelectionAltered();
            base.OnSelectedIndexChanged(e);
        }
        /// <summary>
        /// Capture the parent's mouse move event's to change the controls location
        /// </summary>
        /// <param name="sender">Message sender</param>
        /// <param name="e">Mouse event arguments</param>
        void Parent_MouseMove(object sender, MouseEventArgs e)
        {
            Parent.Location = Parent.Parent.PointToClient(MousePosition);
        }
        /// <summary>
        /// ToString returns display string of the control
        /// </summary>
        /// <returns>Display string of the control</returns>
        public override string ToString()
        {
            return AEUC_DisplayName;
        }
        #endregion

        private void SelectionAltered()
        {
            aeuc_val = AEUC_GetEnumVal(SelectedIndex).AEUC_val;
            AEUC_SetStateChange(true);
            if (AEUC_AUXSetting)
            {
                AEUC_SettingPrimaryLink.AEUC_Val = ((GenAEUCEnumerationItem)SelectedItem).AEUC_val;
                AEUC_SettingSecondaryLink.AEUC_Val = ((GenAEUCEnumerationItem)SelectedItem).AEUC_optval;
            }
        }

        private void UpDateIndexSelection()
        {
            Items.Clear();
            if (enumerationItems.Count > 0)
            {
                for (int i =0; i<enumerationItems.Count; i++)
                {
                    Items.Add(enumerationItems[i]);
                }

                if (OnEnumCollectionUpdate != null)
                    OnEnumCollectionUpdate();
            }
            else
                AEUC_Enabled = false;
        }
        /// <summary>
        /// Empty delegate for event construction
        /// </summary>
        public delegate void EnumCollectionUpdate();
        /// <summary>
        /// Event fired when the combo box selection list gets updated
        /// </summary>
        public event EnumCollectionUpdate OnEnumCollectionUpdate;

        #region IAEUCSetting Members
        /// <summary>
        /// Get or set the AEUC-Setting primary value
        /// </summary>
        public Int64 AEUC_Val
        {
            get
            {
                return aeuc_val;
            }
            set
            {
                aeuc_val = value;

                if (AEUC_LinkedSetting)
                {
                    if (aeuc_val != 0)
                    {
                        aeuc_val = (value & aeuc_max);

                        aeuc_val &= ~(aeuc_min - 1);
                    }

                    IAEUCSetting tmpSet = AEUC_NextSettingLink;

                    while (tmpSet != null && (tmpSet != this && tmpSet != this.Parent))
                    {
                        tmpSet.AEUC_LinkValueSetValue(value);
                        tmpSet = tmpSet.AEUC_NextSettingLink;
                    }
                }

                //SelectedIndex = AEUC_Default;

                for (int i = 0; i < Items.Count; i++)
                {
                    GenAEUCEnumerationItem tmpEnum = AEUC_GetEnumVal(i);
                    if (tmpEnum.AEUC_val == aeuc_val)
                    {
                        SelectedIndex = i;
                        break;
                    }
                }
            }
        }
        /// <summary>
        /// Get or set the AEUC-Setting optional value
        /// </summary>
        public Int64 AEUC_OptVal
        {
            get
            {
                return aeuc_opt_val;
            }
            set
            {
                aeuc_opt_val = value;
            }
        }
        /// <summary>
        /// Get or set the AEUC-Setting default value
        /// </summary>
        public Int64 AEUC_Default
        {
            get
            {
                return aeuc_default;
            }
            set
            {
                aeuc_default = value;
            }
        }
        /// <summary>
        /// Get or set the AEUC-Setting minimum value
        /// </summary>
        public Int64 AEUC_Min
        {
            get
            {
                return aeuc_min;
            }
            set
            {
                aeuc_min = value;
            }
        }
        /// <summary>
        /// Get or set the AEUC-Setting maximum value
        /// </summary>
        public Int64 AEUC_Max
        {
            get
            {
                return aeuc_max;
            }
            set
            {
                aeuc_max = value;
            }
        }
        /// <summary>
        /// Get or set the AEUC-Setting id
        /// </summary>
        public uint AEUC_Id
        {
            get
            {
                return aeuc_id;
            }
            set
            {
                aeuc_id = value;
            }
        }
        /// <summary>
        /// Get or set the AEUC-Setting size
        /// </summary>
        public uint AEUC_Size
        {
            get
            {
                return aeuc_size;
            }
            set
            {
                aeuc_size = value;
            }
        }
        /// <summary>
        /// Get or set current availability of this control
        /// </summary>
        public bool AEUC_Enabled
        {
            get
            {
                return aeuc_enabled;
            }
            set
            {
                if (enumerationItems == null || enumerationItems.Count == 0)
                    aeuc_enabled = false;
                else
                    aeuc_enabled = value;
                if (aeuc_enabled)
                    BackColor = System.Drawing.Color.White;
                else
                    BackColor = System.Drawing.Color.LightGray;
            }
        }
        /// <summary>
        /// Reference pointer
        /// </summary>
        public bool AEUC_RefPointer
        {
            get
            {
                return aeuc_refPtr;
            }
            set
            {
                aeuc_refPtr = value;
            }
        }
        /// <summary>
        /// Set or get current support for state change sense
        /// </summary>
        public bool AEUC_SupportStateSense
        {
            get
            {
                return aeuc_support_state_sense;
            }
            set
            {
                aeuc_support_state_sense = value;
            }
        }
        /// <summary>
        /// Raise the state change flag
        /// </summary>
        public void AEUC_SetStateChange(bool do_itter)
        {
            aeuc_state_changed = true;
            if (AEUC_LinkedSetting && do_itter)
            {
                IAEUCSetting tmpSet = AEUC_NextSettingLink;

                while (tmpSet != null && tmpSet != this && tmpSet != this.Parent)
                {
                    tmpSet.AEUC_SetStateChange(false);
                    tmpSet = tmpSet.AEUC_NextSettingLink;
                }
            }
        }
        /// <summary>
        /// Set the reset the state of the control
        /// </summary>
        public void AEUC_ResetToDefault()
        {
            AEUC_Val = aeuc_default;
        }
        /// <summary>
        /// Composes a generic AEUC-Setting
        /// </summary>
        /// <returns>A generic AEUC-Setting representation</returns>
        public GenAEUCSetting AEUC_GetSetting()
        {
            GenAEUCSetting crntSettings = new GenAEUCSetting();
            crntSettings.AEUC_id = aeuc_id;
            crntSettings.AEUC_size = aeuc_size;
            crntSettings.AEUC_val = new byte[aeuc_size];

            if (SelectedIndex < 0)
                SelectedIndex = (int)AEUC_Default;

            Int64 enum_val = AEUC_GetEnumVal(SelectedIndex).AEUC_val;

            if (AEUC_LinkedSetting)
            {
                if (enum_val != 0 && (enum_val > aeuc_max || enum_val < aeuc_min))
                {
                    throw new Exception("Setting with ID: " + aeuc_id.ToString() + " has value outside of its available set.\n Value: " + enum_val.ToString() + " Accepted min: "+aeuc_min.ToString() + " Accepted max: " + aeuc_max.ToString());
                }
            }
            else
            {
                if ((enum_val > aeuc_max || enum_val < aeuc_min))
                {
                    //throw new Exception("Setting with ID: " + aeuc_id.ToString() + " has value outside of its available set.\n Value: " + enum_val.ToString() + " Accepted min: "+aeuc_min.ToString() + " Accepted max: " + aeuc_max.ToString());
                    MessageBox.Show("Setting with ID: " + aeuc_id.ToString() + " has value outside of its available set.\n Value: " + enum_val.ToString() + " Accepted min: " + aeuc_min.ToString() + " Accepted max: " + aeuc_max.ToString());
                    AEUCSettingEditForm asef = new AEUCSettingEditForm(this);
                    asef.ShowDialog();
                }
            }

            if (AEUC_LinkedSetting)
            {
                IAEUCSetting tmpSet = AEUC_NextSettingLink;

                while (tmpSet != null && tmpSet != this && tmpSet != this.Parent)
                {
                    enum_val |= tmpSet.AEUC_LinkValueAgregation();
                    tmpSet = tmpSet.AEUC_NextSettingLink;
                }
            }

            for (int i = 0; i<aeuc_size; i++)
            {
                crntSettings.AEUC_val[i] = (byte)(enum_val>>(i*8));
            }

            if (AEUC_SupportStateSense)
            {
                if (aeuc_state_changed)
                {
                    aeuc_state_changed = false;
                    return crntSettings;
                }
            }
            else
            {
                return crntSettings;
            }

            return null;
        }
        /// <summary>
        /// Gets or sets the link status of the control
        /// </summary>
        public bool AEUC_LinkedSetting
        {
            get
            {
                return aeuc_linked_setting;
            }
            set
            {
                aeuc_linked_setting = value;
            }
        }
        /// <summary>
        /// Get or set the next control in the link chain, null if none
        /// </summary>
        public IAEUCSetting AEUC_NextSettingLink
        {
            get
            {
                return aeuc_next_linked_setting;
            }
            set
            {
                aeuc_next_linked_setting = value;
            }
        }
        /// <summary>
        /// Get or set the type of the control link chain
        /// </summary>
        public int AEUC_SettingChainType
        {
            get
            {
                return aeuc_linked_setting_type;
            }
            set
            {
                aeuc_linked_setting_type = value;
            }
        }
        /// <summary>
        /// Get or set the auxiliary status of the setting
        /// </summary>
        public bool AEUC_AUXSetting
        {
            get
            {
                return aeuc_isaux;
            }
            set
            {
                aeuc_isaux = value;
            }
        }
        /// <summary>
        /// Get or set the control linked to the primary value of this auxiliary setting
        /// </summary>
        public IAEUCSetting AEUC_SettingPrimaryLink
        {
            get
            {
                return aeuc_aux_primary_link;
            }
            set
            {
                aeuc_aux_primary_link = value;
            }
        }
        /// <summary>
        /// Get or set the control linked to the secondary value of this auxiliary setting
        /// </summary>
        public IAEUCSetting AEUC_SettingSecondaryLink
        {
            get
            {
                return aeuc_aux_secondary_link;
            }
            set
            {
                aeuc_aux_secondary_link = value;
            }
        }
        /// <summary>
        /// Restore the setting value to its shadowed copy
        /// </summary>
        public void AEUC_RestoreShadowedValue()
        {
            AEUC_Val = aeuc_shadow_val;
        }
        /// <summary>
        /// Update the shadowed copy of a setting to its new value
        /// </summary>
        public void AEUC_UpdateShadowedValue()
        {
            aeuc_shadow_val = aeuc_val;
        }
        /// <summary>
        /// Get or set the use of shadowed copy for this settig
        /// </summary>
        public bool AEUC_ShadowedValue
        {
            get
            {
                return aeuc_use_shadow_val;
            }
            set
            {
                aeuc_use_shadow_val = value;
            }
        }
        /// <summary>
        /// Get or set the display string of the control
        /// </summary>
        public string AEUC_DisplayName
        {
            get
            {
                return aeuc_display_name;
            }
            set
            {
                if (Parent != null && Parent.GetType() == typeof(AEUCComboBox))
                {
                    ((AEUCComboBox)Parent).CC_Update_UI_Name(value);
                }
                aeuc_display_name = value;
                Text = aeuc_display_name;
            }
        }
        /// <summary>
        /// When the control array is deserialized from a stream, this function will set the appropirate control links
        /// </summary>
        /// <returns>True if the operation completed successfully</returns>
        public bool AEUC_SetLinkInitialization()
        {
            bool NoError = true;
            try
            {
                if (next_link_reference_number > -1)
                    aeuc_next_linked_setting = ((IAEUCSetting)Parent.Parent.Controls[next_link_reference_number]).AEUC_GetLinkReference();
                else
                    aeuc_next_linked_setting = null;
                if (aux_primary_reference_number > -1)
                    aeuc_aux_primary_link = ((IAEUCSetting)Parent.Parent.Controls[aux_primary_reference_number]).AEUC_GetLinkReference();
                else
                    aeuc_aux_primary_link = null;
                if (aux_secondary_reference_number > -1)
                    aeuc_aux_secondary_link = ((IAEUCSetting)Parent.Parent.Controls[aux_secondary_reference_number]).AEUC_GetLinkReference();
                else
                    aeuc_aux_secondary_link = null;
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
                NoError = false;
            }
            return NoError;
        }
        /// <summary>
        /// Returns the reference to the valid AEUC setting object
        /// </summary>
        /// <returns>vali AEUC setting object</returns>
        public IAEUCSetting AEUC_GetLinkReference()
        {
            return this;
        }
        /// <summary>
        /// Recursive itteration in the linked group to obtain a composite value
        /// </summary>
        /// <returns>Integer value</returns>
        public Int64 AEUC_LinkValueAgregation()
        {
            if (SelectedIndex < 0 || SelectedIndex >= Items.Count)
                SelectedIndex = 0;
            return AEUC_GetEnumVal(SelectedIndex).AEUC_val;
        }
        /// <summary>
        /// Recursive itteration in the linked group to set a composite value
        /// </summary>
        /// <returns>Integer value</returns>
        public void AEUC_LinkValueSetValue(Int64 l_val)
        {
            //SelectedIndex = AEUC_Default;
            aeuc_val = (l_val & aeuc_max);

            aeuc_val &= ~(aeuc_min - 1);

            for (int i = 0; i < Items.Count; i++)
            {
                GenAEUCEnumerationItem tmpEnum = AEUC_GetEnumVal(i);
                if (tmpEnum.AEUC_val == aeuc_val)
                {
                    SelectedIndex = i;
                    break;
                }
            }
        }
        #endregion

        #region IAEUCEnumeration Members
        /// <summary>
        /// Adds an enumeration item to the item array of the control
        /// </summary>
        /// <param name="iDisplay">Display string of the item</param>
        /// <param name="iVal">Primary value</param>
        /// <param name="iOptVal">Optional value</param>
        public void AEUC_AddEnumVal(string iDisplay, Int64 iVal, Int64 iOptVal)
        {
            enumerationItems.Add(new GenAEUCEnumerationItem(iDisplay, iVal, iOptVal));
            UpDateIndexSelection();
        }
        /// <summary>
        /// Deletes an enumeration value at the specified position
        /// </summary>
        /// <param name="iPosition">The position in the item array</param>
        public void AEUC_DeleteEnumVal(int iPosition)
        {
            if (iPosition < enumerationItems.Count)
            {
                enumerationItems.RemoveAt(iPosition);
                UpDateIndexSelection();
            }
        }
        /// <summary>
        /// Returns an enumeration item from the specified position
        /// </summary>
        /// <param name="iPosition">the position within the item array</param>
        /// <returns></returns>
        public GenAEUCEnumerationItem AEUC_GetEnumVal(int iPosition)
        {
            if (iPosition > -1 && iPosition < enumerationItems.Count)
                return enumerationItems[iPosition];
            else
                return null;
        }
        /// <summary>
        /// Changes the values of an enummeration item at a specific position
        /// </summary>
        /// <param name="iPosition">The position within the item array</param>
        /// <param name="iDisplayName">New display name</param>
        /// <param name="iVal">New primary value</param>
        /// <param name="iOptVal">New optional value</param>
        public void AEUC_EditEnumVal(int iPosition, string iDisplayName, Int64 iVal, Int64 iOptVal)
        {
            if (iPosition < enumerationItems.Count)
            {
                enumerationItems[iPosition].AEUC_displayname = iDisplayName;
                enumerationItems[iPosition].AEUC_val = iVal;
                enumerationItems[iPosition].AEUC_optval = iOptVal;
                UpDateIndexSelection();
            }
        }
        #endregion

        #region IAEUCSerialization Members
        /// <summary>
        /// Current element serialization state version
        /// </summary>
        public int serVersion
        {
            get
            {
                return 0x001;
            }
        }
        /// <summary>
        /// Saves this objec instance to a file
        /// </summary>
        /// <param name="srWriter">Binray writer of the associated file</param>
        public void Serialize(System.IO.BinaryWriter srWriter)
        {
            srWriter.Write(serVersion);
            Serialize_v001(srWriter);
        }
        /// <summary>
        /// Loads this objects instance from a file
        /// </summary>
        /// <param name="srReader">Binray reader of the associated file</param>
        /// <returns>Boolean representing the success of the operation</returns>
        public bool Deserialize(System.IO.BinaryReader srReader)
        {
            bool desProcState;
            int serialVer = srReader.ReadInt32();

            switch (serialVer)
            {
                case 0x000:
                    desProcState = Deserialize_v000(srReader);
                    break;
                case 0x001:
                    desProcState = Deserialize_v001(srReader);
                    break;
                default:
                    desProcState = false;
                    break;
            }

            return desProcState;       
        }

        #region Version 0x000 serialization
        /// <summary>
        /// Version 0x000 serialization
        /// </summary>
        /// <param name="srWriter">File writer</param>
        void Serialize_v000(System.IO.BinaryWriter srWriter)
        {
            srWriter.Write(aeuc_val);
            srWriter.Write(aeuc_opt_val);
            srWriter.Write(aeuc_default);
            srWriter.Write(aeuc_min);
            srWriter.Write(aeuc_max);
            srWriter.Write(aeuc_id);
            srWriter.Write(aeuc_size);
            srWriter.Write(aeuc_enabled);
            srWriter.Write(aeuc_support_state_sense);
            srWriter.Write(aeuc_linked_setting);
            srWriter.Write(aeuc_linked_setting_type);
            srWriter.Write(aeuc_isaux);
            srWriter.Write(aeuc_use_shadow_val);
            srWriter.Write(aeuc_display_name);
            #region Save the next link control
            for (int i = 0; i <= Parent.Parent.Controls.Count; i++)
            {
                if (i == Parent.Parent.Controls.Count)
                {
                    srWriter.Write(-1);
                }
                else if ((Parent.Parent.Controls[i]) is IAEUCSetting && ((IAEUCSetting)Parent.Parent.Controls[i]).AEUC_GetLinkReference() == aeuc_next_linked_setting)
                {
                    srWriter.Write(i);
                    i = Parent.Parent.Controls.Count + 1;
                }
            }
            #endregion
            #region Save the primary auxiliary control
            for (int i = 0; i <= Parent.Parent.Controls.Count; i++)
            {
                if (i == Parent.Parent.Controls.Count)
                {
                    srWriter.Write(-1);
                }
                else if ((Parent.Parent.Controls[i]) is IAEUCSetting && ((IAEUCSetting)Parent.Parent.Controls[i]).AEUC_GetLinkReference() == aeuc_aux_primary_link)
                {
                    srWriter.Write(i);
                    i = Parent.Parent.Controls.Count + 1;
                }
            }
            #endregion
            #region Save the secondary auxiliary control
            for (int i = 0; i <= Parent.Parent.Controls.Count; i++)
            {
                if (i == Parent.Parent.Controls.Count)
                {
                    srWriter.Write(-1);
                }
                else if ((Parent.Parent.Controls[i]) is IAEUCSetting && ((IAEUCSetting)Parent.Parent.Controls[i]).AEUC_GetLinkReference() == aeuc_aux_secondary_link)
                {
                    srWriter.Write(i);
                    i = Parent.Parent.Controls.Count + 1;
                }
            }
            #endregion
            #region Save the enumerated settings
            if (enumerationItems.Count > 0)
            {
                srWriter.Write(enumerationItems.Count);
                for (int i = 0; i < enumerationItems.Count; i++)
                {
                    enumerationItems[i].Serialize(srWriter);
                }
            }
            else
            {
                srWriter.Write(-1);
            }
            #endregion
        }
        /// <summary>
        /// Version 0x000 deserialization
        /// </summary>
        /// <param name="srReader">File reader</param>
        /// <returns>True if operation is succesful</returns>
        bool Deserialize_v000(System.IO.BinaryReader srReader)
        {
            bool NoError = true;
            try
            {
                int specLoad;

                AEUC_Val = srReader.ReadInt64();
                AEUC_OptVal = srReader.ReadInt64();
                AEUC_Default = srReader.ReadInt64();
                AEUC_Min = srReader.ReadInt64();
                AEUC_Max = srReader.ReadInt64();
                AEUC_Id = srReader.ReadUInt32();
                AEUC_Size = srReader.ReadUInt32();
                aeuc_enabled = srReader.ReadBoolean();
                AEUC_SupportStateSense = srReader.ReadBoolean();
                AEUC_SetStateChange(false);
                AEUC_LinkedSetting = srReader.ReadBoolean();
                AEUC_SettingChainType = srReader.ReadInt32();
                AEUC_AUXSetting = srReader.ReadBoolean();
                AEUC_UpdateShadowedValue();
                AEUC_ShadowedValue = srReader.ReadBoolean();
                AEUC_DisplayName = srReader.ReadString();
                #region Read the reference numbers of the link and auxiliary controls
                next_link_reference_number = srReader.ReadInt32();
                aux_primary_reference_number = srReader.ReadInt32();
                aux_secondary_reference_number = srReader.ReadInt32();
                #endregion
                #region Load the enumeration items
                specLoad = srReader.ReadInt32();
                for (int i = 0; i < specLoad; i++)
                {
                    GenAEUCEnumerationItem tmpAEnu = new GenAEUCEnumerationItem();
                    NoError = tmpAEnu.Deserialize(srReader);
                    enumerationItems.Add(tmpAEnu);
                }
                AEUC_Enabled = aeuc_enabled;
                UpDateIndexSelection();
                #endregion
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
                NoError = false;
            }
            return NoError;
        }
        #endregion
        #region Version 0x001 serialization
        /// <summary>
        /// Version 0x001 serialization
        /// </summary>
        /// <param name="srWriter">File writer</param>
        void Serialize_v001(System.IO.BinaryWriter srWriter)
        {
            srWriter.Write(aeuc_val);
            srWriter.Write(aeuc_opt_val);
            srWriter.Write(aeuc_default);
            srWriter.Write(aeuc_min);
            srWriter.Write(aeuc_max);
            srWriter.Write(aeuc_id);
            srWriter.Write(aeuc_size);
            srWriter.Write(aeuc_enabled);
            srWriter.Write(aeuc_refPtr);
            srWriter.Write(aeuc_support_state_sense);
            srWriter.Write(aeuc_linked_setting);
            srWriter.Write(aeuc_linked_setting_type);
            srWriter.Write(aeuc_isaux);
            srWriter.Write(aeuc_use_shadow_val);
            srWriter.Write(aeuc_display_name);
            #region Save the next link control
            for (int i = 0; i <= Parent.Parent.Controls.Count; i++)
            {
                if (i == Parent.Parent.Controls.Count)
                {
                    srWriter.Write(-1);
                }
                else if ((Parent.Parent.Controls[i]) is IAEUCSetting && ((IAEUCSetting)Parent.Parent.Controls[i]).AEUC_GetLinkReference() == aeuc_next_linked_setting)
                {
                    srWriter.Write(i);
                    i = Parent.Parent.Controls.Count + 1;
                }
            }
            #endregion
            #region Save the primary auxiliary control
            for (int i = 0; i <= Parent.Parent.Controls.Count; i++)
            {
                if (i == Parent.Parent.Controls.Count)
                {
                    srWriter.Write(-1);
                }
                else if ((Parent.Parent.Controls[i]) is IAEUCSetting && ((IAEUCSetting)Parent.Parent.Controls[i]).AEUC_GetLinkReference() == aeuc_aux_primary_link)
                {
                    srWriter.Write(i);
                    i = Parent.Parent.Controls.Count + 1;
                }
            }
            #endregion
            #region Save the secondary auxiliary control
            for (int i = 0; i <= Parent.Parent.Controls.Count; i++)
            {
                if (i == Parent.Parent.Controls.Count)
                {
                    srWriter.Write(-1);
                }
                else if ((Parent.Parent.Controls[i]) is IAEUCSetting && ((IAEUCSetting)Parent.Parent.Controls[i]).AEUC_GetLinkReference() == aeuc_aux_secondary_link)
                {
                    srWriter.Write(i);
                    i = Parent.Parent.Controls.Count + 1;
                }
            }
            #endregion
            #region Save the enumerated settings
            if (enumerationItems.Count > 0)
            {
                srWriter.Write(enumerationItems.Count);
                for (int i = 0; i < enumerationItems.Count; i++)
                {
                    enumerationItems[i].Serialize(srWriter);
                }
            }
            else
            {
                srWriter.Write(-1);
            }
            #endregion
        }
        /// <summary>
        /// Version 0x001 deserialization
        /// </summary>
        /// <param name="srReader">File reader</param>
        /// <returns>True if operation is succesful</returns>
        bool Deserialize_v001(System.IO.BinaryReader srReader)
        {
            bool NoError = true;
            try
            {
                int specLoad;

                AEUC_Val = srReader.ReadInt64();
                AEUC_OptVal = srReader.ReadInt64();
                AEUC_Default = srReader.ReadInt64();
                AEUC_Min = srReader.ReadInt64();
                AEUC_Max = srReader.ReadInt64();
                AEUC_Id = srReader.ReadUInt32();
                AEUC_Size = srReader.ReadUInt32();
                aeuc_enabled = srReader.ReadBoolean();
                AEUC_RefPointer = srReader.ReadBoolean();
                AEUC_SupportStateSense = srReader.ReadBoolean();
                AEUC_SetStateChange(false);
                AEUC_LinkedSetting = srReader.ReadBoolean();
                AEUC_SettingChainType = srReader.ReadInt32();
                AEUC_AUXSetting = srReader.ReadBoolean();
                AEUC_UpdateShadowedValue();
                AEUC_ShadowedValue = srReader.ReadBoolean();
                AEUC_DisplayName = srReader.ReadString();
                #region Read the reference numbers of the link and auxiliary controls
                next_link_reference_number = srReader.ReadInt32();
                aux_primary_reference_number = srReader.ReadInt32();
                aux_secondary_reference_number = srReader.ReadInt32();
                #endregion
                #region Load the enumeration items
                specLoad = srReader.ReadInt32();
                for (int i = 0; i < specLoad; i++)
                {
                    GenAEUCEnumerationItem tmpAEnu = new GenAEUCEnumerationItem();
                    NoError = tmpAEnu.Deserialize(srReader);
                    enumerationItems.Add(tmpAEnu);
                }
                AEUC_Enabled = aeuc_enabled;
                UpDateIndexSelection();
                #endregion
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
                NoError = false;
            }
            return NoError;
        }
        #endregion
        #endregion
    }
}
